package com.fm.demo.utils

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.rxLifeScope
import com.fm.common.net.baseCoroutine.exception.then
import com.fm.common.net.code
import com.fm.common.net.msg
import com.fm.common.utils.showDarkToast
import kotlinx.coroutines.async
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toResponse

object HttpUtils {
    inline fun <reified T : Any> buildPost(
        ower: LifecycleOwner,
        url: String,
        params: HashMap<String, Any>?,
        noinline then: ((T?) -> Unit)? = null,
        noinline error: ((it: Throwable) -> Unit)? = null,
        showDialog: Boolean = true
    ) {
        if (showDialog) {
            DialogUtils.showLoadingDialog()
        }
        ower.lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    DialogUtils.dismissLoadingDialog()
                    ower.lifecycle.removeObserver(this)
                }
            }
        })
        ower.rxLifeScope.launch({
            async {
                val parsm = RxHttp.postJson(url).setDomainToJokeIfAbsent().setHeader("Accept", "application/json;charset=UTF-8")
                params?.let { param ->
                    for (map in param) {
                        parsm.add(map.key, map.value)
                    }
                }
                parsm.toResponse<T>().await()
            }.then {
                then?.invoke(it)
                DialogUtils.dismissLoadingDialog()
            }
        }, {
            DialogUtils.dismissLoadingDialog()
            when (it.code) {
                200 -> {
                    then?.invoke(null)
                }
                else -> {
                    if (null == error) {
                        showDarkToast(it.msg)
                    } else {
                        error.invoke(it)
                    }
                }
            }
        })
    }
}